home *** CD-ROM | disk | FTP | other *** search
/ SGI Varsity Update 1998 August / SGI Varsity Update 1998 August.iso / dist / SpeedShop.idb / usr / demos / SpeedShop / generic / generic.c.z / generic.c
C/C++ Source or Header  |  1998-07-29  |  36KB  |  1,701 lines

  1. /* generic.c - generic program to use for testing performance tools */
  2.  
  3. #include    <sys/types.h>
  4. #include    <dirent.h>
  5. #include    <stdlib.h>
  6. #include    <stdio.h>
  7. #include    <errno.h>
  8. #include    <malloc.h>
  9. #include    <sys/stat.h>
  10. #include    <dlfcn.h>
  11. #include    <signal.h>
  12. #include    <sys/prctl.h>
  13. #include    <ulocks.h>
  14. #include    <fcntl.h>
  15.  
  16. /* parameters defining various tasks */
  17. #define    BUFSIZE        16384
  18. #define    THRASHMB    32
  19. #define    DIRNAME        "/usr/include"
  20. #define    IONAME        "/unix"
  21. #define    DYNSOROUTINE    "dlslave_routine"
  22. #define    DYNSONAME    "./dlslave.so"
  23.  
  24. #define    NSPROCS        8
  25. #define    NBEERBOTTLES    5
  26. #define    NSPROCMALLOCS    5
  27.  
  28. /* the default script */
  29. #define    DEFAULT_SCRIPT    "ll.u.cvt.d.i.f.dso"
  30.  
  31. void    Scriptstring(char *);    /* routine execute a scenario */
  32.  
  33. void    genLog(char *);    /* write to log */
  34. void    clone(char *);    /* fork copy of self to run string */
  35. void    reapAll(void);    /* reap all children */
  36. void    reapSig(int);    /* reap a child after getting SIGCLD */
  37.  
  38. /* various behavior routines */
  39. int    adddso(void);        /* add a DSO and call a routine in the DSO */
  40. int    beerbottles(void);    /* exec beerbottles */
  41. int    callsystem(void);    /* call system to generate another process */
  42. int    cvttrap(void);        /* generate unimplemented FP traps */
  43. int    dirstat(void);        /* scan a directory, and stat its files */
  44. int    exectest(void);        /* fork, and exec a program in the child */
  45. int    fpetraps(void);        /* generate a bunch of fpe's */
  46. int    forceabort(void);    /* force a SEGV by dereferencing NULL */
  47. int    iofile(void);        /* do some iofile */
  48. int    iotest(void);        /* various other io syscall tests */
  49. int    libdso(void);        /* link and call a routine in a DSO */
  50. int    libdsoclose(void);    /* dlclose a DSO */
  51. int    linklist(void);        /* build a linked list of structures */
  52. int    mallocerrors(void);    /* make verious kinds of malloc errors */
  53. int    mallocerrors_extra(void);    /* malloc errors - extra */
  54. int    mp_mallocs(void);    /* multi-processes calling "me" and "mex" */
  55. int    memthrash(void);    /* thrash around in memory */
  56. int    sproctest(void);    /* sproc, and run a routine in the child */
  57. int    usrtime(void);        /* use a bunch of user time */
  58. void    anneal();        /* array annealing test */
  59.  
  60. /* lookup table for behavior scripts */
  61. struct    scripttab {
  62.     char    *name;
  63.     int (*function)(void);
  64. };
  65.  
  66. struct    scripttab    scripttab[] = {
  67.     "bb", beerbottles,
  68.     "callsys", callsystem,
  69.     "cvt", cvttrap,
  70.     "d", dirstat,
  71.     "ex", exectest,
  72.     "f", fpetraps,
  73.     "segv", forceabort,
  74.     "i", iofile,
  75.     "I", iotest,
  76.     "ll", linklist,
  77. #ifndef NONSHARED
  78.     "dso", libdso,
  79.     "dsoclose", libdsoclose,
  80.     "adddso", adddso,
  81.     "me", mallocerrors,
  82.     "mex", mallocerrors_extra,
  83.     "mpmes", mp_mallocs,    /* MP malloc-error tests (me + mex) */
  84. #endif
  85.     "t", memthrash,
  86.     "sp", sproctest,
  87.     "u", usrtime,
  88.     NULL, NULL
  89. };
  90.  
  91. void    sproctestchild(void *);    /* sproc child code */
  92. void    sproctestgrandchild(void *);    /* sproc grandchild code */
  93.  
  94. static    struct timeval    starttime;    /* starting time - first timestamp */
  95. static    struct timeval    ttime;        /* last-recorded timestamp */
  96. static    struct timeval    deltatime;
  97.  
  98. int    pagesize;
  99.  
  100. main(unsigned argc, char **argv)
  101. {
  102.     int    i;
  103.  
  104.     /* initialize the timestamp */
  105.     (void) gettimeofday(&starttime, NULL);
  106.  
  107.     /* set up to reap any children */
  108.     (void) sigset(SIGCHLD, (SIG_PF)reapSig);
  109.  
  110.     if(argc == 1) {
  111.         Scriptstring(DEFAULT_SCRIPT);
  112.         exit(0);
  113.     } else {
  114.  
  115.         i = argc;
  116.         while(i > 2) {
  117.             clone(argv[i-1]);
  118.             i --;
  119.         }
  120.         Scriptstring(argv[i-1]);
  121.     }
  122.     reapAll();
  123.     exit(0);
  124. }
  125.  
  126. /* clone -- fork a copy to run a script */
  127. void
  128. clone(char *script)
  129. {
  130.     int    child_pid;
  131.  
  132.     /* Log the event */
  133.     genLog("cloning ... ");
  134.  
  135.     /* fork a new process */
  136.     child_pid = fork();
  137.     if (child_pid < 0) {
  138.  
  139.         /* error, could not fork */
  140.         fprintf(stderr, "clone: fork failed--%s\n",
  141.             sys_errlist[errno]);
  142.         return;
  143.  
  144.     } else if(child_pid == 0) {
  145.  
  146.         /* execute the script */
  147.         Scriptstring(script);
  148.         reapAll();
  149.         exit(0);
  150.     }
  151.  
  152.     fprintf(stderr, "child process %d cloned by %d.\n",
  153.         child_pid, getpid() );
  154. }
  155.  
  156. /* reap a child process in response to SIGCLD */
  157. void
  158. reapSig( int sig)
  159. {
  160.     int status;
  161.  
  162.     (void) wait(&status);
  163.     sigset(SIGCLD, reapSig);
  164. }
  165.  
  166. /* reap all child processes prior to exit */
  167. void
  168. reapAll()
  169. {
  170.     int status;
  171.  
  172.     /* wait for all children to exit */
  173.     for(;;) {
  174.         while(wait(&status) != -1) { };
  175.         if(errno == ECHILD) {
  176.             return;
  177.         }
  178.     }
  179. }
  180.  
  181. /* a default scenario: does a number of different phases sequentially */
  182. void
  183. Scriptstring(char *script)
  184. {
  185.     char    *cmd;
  186.     char    *j;
  187.     char    prevj;
  188.     struct    scripttab    *k;
  189.     char    buf[1024];
  190.  
  191.     /* Log the event */
  192.     genLog("Begin script");
  193.     sprintf(buf, "\tbegin script `%s'\n", script);
  194.     fprintf(stderr, buf);
  195.     cmd = script;
  196.  
  197.     while( (*cmd) != 0 ){
  198.         /* find the end of the next phase (a . or NULL) */
  199.         j = cmd;
  200.         while( ((*j) != 0) && ((*j) != '.') ) {
  201.             j++;
  202.         }
  203.  
  204.         prevj = *j;
  205.         *j = 0;
  206.  
  207.         /* now look up the phase in the table */
  208.         for (k = &scripttab[0]; ; k++) {
  209.             if(k->name == NULL) {
  210.                 break;
  211.             }
  212.             if(strcmp(cmd, k->name) == 0) {
  213.                 /* found a match */
  214.                 (k->function)();
  215.                 break;
  216.             }
  217.         }
  218.  
  219.         if(k->name == NULL) {
  220.             sprintf(buf, "++ ignoring `%s'\n", cmd);
  221.             fprintf(stderr, buf);
  222.         }
  223.  
  224.         /* continue processing */
  225.         *j = prevj;
  226.         cmd = j;
  227.         if(prevj != 0) {
  228.             cmd ++;
  229.         }
  230.     }
  231.  
  232.     sprintf(buf, "\tend of script `%s'\n", script);
  233.     fprintf(stderr, buf);
  234.     genLog("End script");
  235. }
  236.  
  237. /* Simple routines to execute various types of behaviors */
  238.  
  239. /*=======================================================*/
  240. /* adddso -- add a DSO using sgidladd function */
  241. #ifndef NONSHARED
  242.  
  243. static    void    *dl_object = NULL;
  244.  
  245. int
  246. adddso()
  247. {
  248.         int i;
  249.  
  250.         /* see if already linked */
  251.         if(dl_object != NULL) {
  252.             fprintf(stderr, "libdso: dl_object already linked\n");
  253.             return 0;
  254.         }
  255.  
  256.         /* Log the event */
  257.         genLog("start of adddso");
  258.  
  259.         /* open the dynamic shared object */
  260.         dl_object = sgidladd(DYNSONAME, RTLD_LAZY);
  261.         if(dl_object == NULL) {
  262.             fprintf(stderr,
  263.                 "adddso: sgidladd of %s failed--%s\n",
  264.                 DYNSONAME, dlerror());
  265.             return 0;
  266.         }
  267.  
  268.         /* invoke the routine */
  269.         i = dlslave_routine();
  270.         fprintf(stderr, "\tadddso: dynamic routine returned %d\n", i);
  271.  
  272.     return 0;
  273. }
  274. #endif
  275.  
  276. /*=======================================================*/
  277. /* beerbottles -- iterative exec */
  278. int
  279. beerbottles()
  280. {
  281.     char    count[1024];
  282.     int    n = NBEERBOTTLES;
  283.  
  284.     /* Log the event */
  285.     genLog("start of beerbottles");
  286.  
  287.     sprintf(count, "%d", n);
  288.     execl("beerbottles", "beerbottles", count, NULL);
  289.     fprintf(stderr, "exectest: execl of `beerbottles' failed--%s\n",
  290.             sys_errlist[errno]);
  291.     exit(1);
  292.  
  293.     return 0;
  294. }
  295.  
  296. /*=======================================================*/
  297. /* callsystem -- use system() to echo a string */
  298. int
  299. callsystem()
  300. {
  301.     /* Log the event */
  302.     genLog("start of callsystem");
  303.  
  304.     /* do the call */
  305.     system("echo \"system(echo) called from callsystem.\"");
  306.  
  307.     fprintf(stderr, "\tcallsystem completed.\n");
  308.  
  309.     return 0;
  310. }
  311.  
  312. /*=======================================================*/
  313. /*    cvttrap - generate a bunch of FP traps (on some machines) */
  314. #define IMAX 500000
  315. int
  316. cvttrap()
  317. {
  318.     float y,z;
  319.     long i,n;
  320.  
  321.     /* Log the event */
  322.     genLog("start of cvttrap");
  323.  
  324.     y = 0.;
  325.     n = (long) 0x1f1f1f1f1f1f1f;
  326.  
  327.     for(i = 0; i < IMAX; i ++ ) {
  328.         y = y + (float)n;
  329.     }
  330.  
  331.     z = 0.;
  332.     n = (long) 0x1f1f1f1f1f;
  333.  
  334.     for(i = 0; i < IMAX; i ++ ) {
  335.         z = z + (float)n;
  336.     }
  337.  
  338.     fprintf(stderr, "\tcvttrap completed, y = %g, z = %g.\n",
  339.         y, z );
  340.  
  341.     return 0;
  342. }
  343.  
  344. /*=======================================================*/
  345. /*    dirstat - open a directory, stat its files */
  346. int
  347. dirstat()
  348. {
  349.     char    *dirname = DIRNAME;
  350.     DIR    *dirp;
  351.     struct    dirent    *direntp;
  352.     int    j = 0;    /* count of entries read */
  353.     struct    stat    statb;
  354.     struct    stat    *statp = &statb;
  355.     char    buf[1024];
  356.  
  357.     /* Log the event */
  358.     genLog("start of dirstat");
  359.  
  360.     /* open the directory */
  361.     dirp = opendir(dirname);
  362.     if(dirp == NULL) {
  363.         /* can't open the directory, just return */
  364.         return 0;
  365.     }
  366.  
  367.     for (;;) {
  368.         direntp = readdir(dirp);
  369.         if(direntp == NULL) {
  370.             /* end of the directory */
  371.             sprintf(buf,
  372.                 "\tdirstat of %s completed, %d files.\n",
  373.                 dirname, j);
  374.             fprintf(stderr, buf);
  375.             closedir(dirp);
  376.             return 0;
  377.         }
  378.         j++;
  379.  
  380.         /* got another entry, stat it */
  381.         (void) stat(direntp->d_name, statp);
  382.     }
  383. }
  384.  
  385. /*=======================================================*/
  386. /*    exectest -- exec "nullprog" */
  387. int
  388. exectest()
  389. {
  390.     /* Log the event */
  391.     genLog("start of exectest");
  392.  
  393.     execl("nullprog", "nullprog", NULL);
  394.     fprintf(stderr, "exectest: execl of `nullprog' failed--%s\n",
  395.             sys_errlist[errno]);
  396.     exit(1);
  397.  
  398.     return 0;
  399. }
  400.  
  401. /*=======================================================*/
  402. /*    fpetraps - generate a bunch of fpe traps */
  403. int
  404. fpetraps()
  405. {
  406.     int    k;
  407.     float    x, y, z;
  408.  
  409.     /* Log the event */
  410.     genLog("start of fpetraps");
  411.  
  412.     /* do some underflows */
  413.     x = 0.3;
  414.     for (k = 0; k < 10; k ++) {
  415.         x = x * x;
  416.     }
  417.  
  418.     /* do some overflows */
  419.     x = 3.;
  420.     for (k = 0; k < 10; k ++) {
  421.         x = x * x;
  422.     }
  423.  
  424.     /* divide by zero */
  425.     y = 0.;
  426.     x = 10.;
  427.     z = x/y;
  428.     x = z;
  429.  
  430.     /* generate indefinite: 0/0 */
  431.     x = 0;
  432.     z = x/y;
  433.     x = z;
  434.  
  435.     fprintf(stderr, "\tfpetraps completed.\n");
  436.  
  437.     return 0;
  438. }
  439.  
  440. /*=======================================================*/
  441. /*    forceabort - force a SEGV */
  442. int
  443. forceabort()
  444. {
  445.     char    *fname = NULL;
  446.     FILE    *fp;    /* FILE pointer for stdio */
  447.     int    k;    /* temp value for loop */
  448.     char    c;
  449.     u_int    size = 0;
  450.  
  451.     /* Log the event */
  452.     genLog("start of forceabort");
  453.  
  454.     /* and dereference a NULL */
  455.     c = *fname;
  456.  
  457.     return 0;
  458. }
  459.  
  460. /*=======================================================*/
  461. /*    iofile - do some file io operations */
  462. int
  463. iofile()
  464. {
  465.     char    *fname = IONAME;
  466.     FILE    *fp;    /* FILE pointer for stdio */
  467.     int    k;    /* temp value for loop */
  468.     char    *buf;
  469.     u_int    size = 0;
  470.  
  471.     /* Log the event */
  472.     genLog("start of iofile -- stdio");
  473.  
  474.     /* allocate a buffer for the reading */
  475.     /* note that this buffer is leaked! */
  476.     buf = (char *) malloc(BUFSIZE);
  477.  
  478.     /* open the file */
  479.     fp = fopen(fname, "r");
  480.  
  481.     /* loop, reading into the buffer */
  482.     for(;;) {
  483.         k = fread(buf, sizeof(char), BUFSIZE, fp);
  484.         if (k < 0) {
  485.             fprintf(stderr, "++ERROR reading %s, %s (%d)\n",
  486.                 fname, sys_errlist[errno], errno );
  487.         } else {
  488.             size = size + k;
  489.         }
  490.         if (k != BUFSIZE) {
  491.             /* close the file */
  492.             fclose(fp);
  493.  
  494.             /* short eread = EOF */
  495.             sprintf(buf,
  496.         "\tstdio iofile on %s completed, %d chars.\n",
  497.                 fname, size);
  498.             fprintf(stderr, buf);
  499.             break;
  500.         }
  501.     }
  502.     return 0;
  503. }
  504.  
  505. /*=======================================================*/
  506. /*    iotest - do various io syscalls */
  507. int
  508. iotest()
  509. {
  510.     char    *fname = "/usr/tmp/foobar";
  511.     int    fd;    /* file descriptor for raw IO */
  512.     int    fd2;    /* file descriptor for raw IO */
  513.     int    k;    /* temp value for loop */
  514.     char    *buf;
  515.     u_int    size = 0;
  516.  
  517.     /* Log the regular read */
  518.     genLog("start of iotest");
  519.  
  520.     /* create an empty file */
  521.     fd = creat(fname, 0666);
  522.  
  523.     /* dup the file descriptor */
  524.     fd2 = dup(fd);
  525.     close(fd2);
  526.     close(fd);
  527.  
  528.     /* now open the empty file */
  529.     fd = open(fname, O_RDONLY);
  530.  
  531.     /* loop, reading into the buffer */
  532.     size = 0;
  533.     for(;;) {
  534.         k = read(fd, buf, BUFSIZE);
  535.         if (k < 0) {
  536.             fprintf(stderr, "++ERROR reading %s, %s (%d)\n",
  537.                 fname, sys_errlist[errno], errno );
  538.         } else {
  539.             size = size + k;
  540.         }
  541.         if (k != BUFSIZE) {
  542.             /* close the file */
  543.             close(fd);
  544.  
  545.             /* short eread = EOF */
  546.             break;
  547.         }
  548.     }
  549.  
  550.     /* remove the file */
  551.     unlink(fname);
  552.  
  553.     fprintf(stderr, "\tiotest completed.\n");
  554.     return 0;
  555. }
  556.  
  557. /*=======================================================*/
  558. /* linklist -- build a linked list of structures */
  559.  
  560. struct ll {
  561.     struct    ll *next;
  562.     int    index;
  563.     struct    scripttab *tabentry;
  564.     char    *name;
  565.     int (*function)(void);
  566. };
  567.  
  568. struct    ll    *ll_first = NULL;
  569. struct    ll    *ll_last = NULL;
  570.  
  571. int
  572. linklist()
  573. {
  574.     int i;
  575.     struct    scripttab    *k;
  576.     struct    ll    *ll_new;
  577.  
  578.     /* Log the event */
  579.     genLog("start of linklist");
  580.  
  581.     /* search the task table */
  582.     i = 0;
  583.     for (k = &scripttab[0]; ; k++) {
  584.         if(k->name == NULL) {
  585.             break;
  586.         }
  587.  
  588.         /* allocate a structure */
  589.         ll_new = malloc(sizeof(struct ll) );
  590.  
  591.         /* fill it in */
  592.         ll_new->next = NULL;
  593.         ll_new->index = i;
  594.         ll_new->tabentry = k;
  595.         ll_new->name =strdup(k->name);
  596.         ll_new->function = k->function;
  597.  
  598.         /* link it into the list */
  599.         if (ll_first == NULL) {
  600.             ll_first = ll_new;
  601.         } else {
  602.             ll_last->next = ll_new;
  603.         }
  604.         ll_last = ll_new;
  605.  
  606.         /* bump the index */
  607.         i ++;
  608.     }
  609.     fprintf(stderr, "\tlinklist completed.\n");
  610.     return 0;
  611. }
  612.  
  613. /*=======================================================*/
  614. /* libdso -- dynamically link a DSO, and call a routine in it */
  615.  
  616. #ifndef NONSHARED
  617. int
  618. libdso()
  619. {
  620.     int i;
  621.     int (*dl_routine)();
  622.     char    buf[1024];
  623.  
  624.     /* see if already linked */
  625.     if(dl_object != NULL) {
  626.         fprintf(stderr, "libdso: dl_object already linked\n");
  627.         return 0;
  628.     }
  629.  
  630.     /* Log the event */
  631.     genLog("start of libdso");
  632.  
  633.     /* open the dynamic shared object */
  634.     dl_object = dlopen(DYNSONAME, RTLD_NOW);
  635.     if(dl_object == NULL) {
  636.         fprintf(stderr, "libdso: dlopen of %s failed--%s\n",
  637.             DYNSONAME, dlerror());
  638.         return 0;
  639.     }
  640.  
  641.     /* look up the routine name in it */
  642.     dl_routine = (int (*)())dlsym(dl_object, DYNSOROUTINE);
  643.     if(dl_routine == NULL) {
  644.         fprintf(stderr, "libdso: dlsym %s not found\n",
  645.             DYNSOROUTINE);
  646.         return 0;
  647.     }
  648.  
  649.     /* invoke the routine */
  650.     i = (*dl_routine)();
  651.     sprintf(buf, "\tlibdso: dynamic routine returned %d\n", i);
  652.     fprintf(stderr, buf);
  653.  
  654.     return 0;
  655. }
  656.  
  657. /*=======================================================*/
  658. /* libdsoclose -- close a DSO */
  659. int
  660. libdsoclose()
  661. {
  662.     int rc;
  663.  
  664.     /* ensure already linked */
  665.     if(dl_object == NULL) {
  666.         fprintf(stderr, "libdsoclose: dl_object not linked\n");
  667.         return 0;
  668.     }
  669.  
  670.     /* Log the event */
  671.     genLog("start of libdsoclose");
  672.  
  673.     /* close the dynamic shared object */
  674.     rc = dlclose(dl_object);
  675.     if(rc != 0) {
  676.         fprintf(stderr, "libdso: dlclose failed--%s\n",
  677.             dlerror());
  678.         return 0;
  679.     }
  680.  
  681.     /* clear the pointer */
  682.     dl_object = NULL;
  683.     fprintf(stderr, "\tlibdsoclose completed.\n");
  684.  
  685.     return 0;
  686. }
  687. #endif
  688.  
  689. /*=======================================================*/
  690. /*    mallocerrors - allocate various blocks; make errors */
  691. #ifndef NONSHARED
  692.  
  693. #define    SIMPLE_SIZE    2047
  694.  
  695. /* find the CLEAR_FREE and CLEAR_MALLOC pattern size */
  696. #if    _MIPS_SZPTR == 32
  697. typedef    u_int32_t        CLEAR_WORD;
  698. #define    MPRINT(ARG)        fprintf(stderr, "0x%08x", ARG)
  699. #else
  700. typedef    unsigned long long    CLEAR_WORD;
  701. #define    MPRINT(ARG)        fprintf(stderr, "0x%016llx", ARG)
  702. #endif
  703.  
  704. static void
  705. memcheck(void * ptr, int length)
  706. {
  707.     CLEAR_WORD     *mclear_ptr, mclear, leftover;
  708.     int             i;
  709.  
  710.     if (leftover = ((CLEAR_WORD) ptr % sizeof(CLEAR_WORD))) {
  711.         ptr = (void *) ((char *) ptr + sizeof(CLEAR_WORD) - leftover);
  712.         length -= sizeof(CLEAR_WORD) - leftover;
  713.     }
  714.     if (length < sizeof(CLEAR_WORD)) {
  715.         fprintf(stderr, "Memory check bypassed (length is too small).");
  716.     }
  717.     mclear_ptr = (CLEAR_WORD *) ptr;
  718.     mclear = mclear_ptr[0];
  719.     for (i = 1; i < length / sizeof (CLEAR_WORD); i++)
  720.         if (mclear != mclear_ptr[i]) {
  721.             mclear = mclear_ptr[i];
  722.             break;
  723.         }
  724.     if (mclear != mclear_ptr[0]) {
  725.         fprintf(stderr, "different values in memory block.");
  726.     } else {
  727.         fprintf(stderr, "same value (");
  728.         MPRINT(mclear);
  729.         fprintf(stderr, ") in memory block.");
  730.     }
  731. }
  732.  
  733. int
  734. mallocerrors()
  735. {
  736.     long long stackvar;
  737.     int ralph;
  738.     char *simple;
  739.     char *csimple;
  740.     char *clear;
  741.     char *clear2;
  742.     char *page;
  743.     int alignment;
  744.     long long *mal;
  745.  
  746.     /* Log the event */
  747.     genLog("start of mallocerrors");
  748.  
  749.     /* a simple malloc and free */
  750.     fprintf(stderr, "  Simple malloc(%d)\n", SIMPLE_SIZE);
  751.     if (simple = (char *)malloc(SIMPLE_SIZE)) {
  752.         fprintf(stderr, "    succeeded, block address ");
  753.         MPRINT(simple);
  754.         fprintf(stderr, "\n");
  755.  
  756.         /* check MALLOC_CLEAR_MALLOC */
  757.         fprintf(stderr, "    ");
  758.         memcheck((void *) simple, SIMPLE_SIZE);
  759.         fprintf(stderr, "\n");
  760.  
  761.         /* free simple */
  762.         fprintf(stderr, "    freeing block @");
  763.         MPRINT(simple);
  764.         fprintf(stderr, "...\n");
  765.         free(simple);
  766.  
  767.         /* check MALLOC_CLEAR_FREE */
  768.         fprintf(stderr, "    ");
  769.         memcheck((void *) simple, SIMPLE_SIZE);
  770.         fprintf(stderr, "\n");
  771.     } else {
  772.         fprintf(stderr, "    failed\n");
  773.     }
  774.  
  775.     /* a malloc for a string without zero-byte, and overrun it */
  776.     fprintf(stderr, "  Trying malloc(strlen(\"bad\"))...\n");
  777.     if (csimple = (char *)malloc(strlen("bad") )) {
  778.         fprintf(stderr, "    succeeded, block address ");
  779.         MPRINT(csimple);
  780.         fprintf(stderr, "\n");
  781.  
  782.         fprintf(stderr, "    then copy \"bad\" to it using strcpy()\n");
  783.         strcpy(csimple, "bad");
  784.         fprintf(stderr, "    then free it...\n");
  785.         free(csimple);
  786.     } else {
  787.         fprintf(stderr, "    failed\n");
  788.     }
  789.  
  790.     /* a simple malloc, followed by overrun */
  791.     fprintf(stderr, "  Trying malloc(%d)...\n", SIMPLE_SIZE);
  792.     if (simple = (char *)malloc(SIMPLE_SIZE)) {
  793.         fprintf(stderr, "    succeeded, block address ");
  794.         MPRINT(simple);
  795.         fprintf(stderr, "\n");
  796.  
  797.         fprintf(stderr, "    then write to array[size + 1]...\n");
  798.         simple[SIMPLE_SIZE + 1] = 0;
  799.         fprintf(stderr, "    and free it...\n");
  800.         free(simple);
  801.     } else {
  802.         fprintf(stderr, "    failed\n");
  803.     }
  804.  
  805.     /* a calloc, followed by a realloc */
  806.     fprintf(stderr, "  Trying calloc(1010, 2)...\n");
  807.     if (clear = (char *)calloc(1010, 2)) {
  808.         fprintf(stderr, "    succeeded, block address ");
  809.         MPRINT(clear);
  810.         fprintf(stderr, "\n");
  811.  
  812.         fprintf(stderr, "    ");
  813.         memcheck((void *) clear, 2020);
  814.         fprintf(stderr, "\n");
  815.  
  816.         fprintf(stderr, "    then realloc() to 3000...\n");
  817.         if (clear2 = (char *)realloc((void*)clear, 3000)) {
  818.             fprintf(stderr, "      succeeded, block address ");
  819.             MPRINT(clear2);
  820.             fprintf(stderr, "\n");
  821.  
  822.             fprintf(stderr, "      ");
  823.             memcheck((void *) clear2, 3000);
  824.             fprintf(stderr, "\n");
  825.  
  826.             fprintf(stderr, "      then free it...\n");
  827.             free(clear2);
  828.  
  829.             fprintf(stderr, "      ");
  830.             memcheck((void *) clear2, 3000);
  831.             fprintf(stderr, "\n");
  832.         } else {
  833.             fprintf(stderr, "      failed\n");
  834.             fprintf(stderr, "    Maybe free the old pointer?\n");
  835.             free(clear);
  836.         }
  837.     } else {
  838.         fprintf(stderr, "    failed\n");
  839.     }
  840.  
  841.     /* malloc 1 byte, then realloc to 3 */
  842.     fprintf(stderr, "  Allocate one byte...\n");
  843.     if (simple = (char *)malloc(1)) {
  844.         fprintf(stderr, "    succeeded, block address ");
  845.         MPRINT(simple);
  846.         fprintf(stderr, "\n");
  847.  
  848.         fprintf(stderr, "    realloc() to 3 bytes...\n");
  849.         if (csimple = (char *)realloc(simple, 3)) {
  850.             fprintf(stderr, "      succeeded, block address ");
  851.             MPRINT(csimple);
  852.             fprintf(stderr, "\n");
  853.  
  854.             fprintf(stderr, "      then free it...\n");
  855.             free(csimple);
  856.         } else {
  857.             fprintf(stderr, "      failed\n");
  858.             fprintf(stderr, "    Maybe free the old pointer?\n");
  859.             free(simple);
  860.         }
  861.     } else {
  862.         fprintf(stderr, "    failed\n");
  863.     }
  864.  
  865.     /* malloc 31 bytes, then realloc to 1 */
  866.     fprintf(stderr, "  Allocate 31 bytes...\n");
  867.     if (simple = (char *)malloc(31)) {
  868.         fprintf(stderr, "    succeeded, block address ");
  869.         MPRINT(simple);
  870.         fprintf(stderr, "\n");
  871.  
  872.         fprintf(stderr, "    realloc() to 1 bytes...\n");
  873.         if (csimple = (char *)realloc(simple, 1)) {
  874.             fprintf(stderr, "      succeeded, block address ");
  875.             MPRINT(csimple);
  876.             fprintf(stderr, "\n");
  877.  
  878.             fprintf(stderr, "      then free it...\n");
  879.             free(csimple);
  880.         } else {
  881.             fprintf(stderr, "      failed\n");
  882.             fprintf(stderr, "    Maybe free the old pointer?\n");
  883.             free(simple);
  884.         }
  885.     } else {
  886.         fprintf(stderr, "    failed\n");
  887.     }
  888.  
  889.     /* a valloc */
  890.     fprintf(stderr, "  Try valloc(%d)...\n", SIMPLE_SIZE);
  891.     if (page = (char *)valloc(SIMPLE_SIZE)) {
  892.         fprintf(stderr, "    succeeded, block address ");
  893.         MPRINT(page);
  894.         fprintf(stderr, "\n");
  895.  
  896.         fprintf(stderr, "    free it...\n");
  897.         free(page);
  898.     } else {
  899.         fprintf(stderr, "    failed\n");
  900.     }
  901.  
  902.     /* a memalign to 16 bytes */
  903.     fprintf(stderr, "  A memalign() at 16-byte boundary...\n");
  904.     alignment = 16;
  905.     if (mal = (long long *)memalign(alignment, 40*sizeof(long long))) {
  906.         fprintf(stderr, "    succeeded, block address ");
  907.         MPRINT(mal);
  908.         fprintf(stderr, "\n");
  909.  
  910.         fprintf(stderr, "    free it...\n");
  911.         free(mal);
  912.     } else {
  913.         fprintf(stderr, "    failed\n");
  914.     }
  915.  
  916.     /* a memalign to 16 bytes, check overrun */
  917.     fprintf(stderr, "  Another memalign() at 16-byte boundary, 3 bytes\n");
  918.     alignment = 16;
  919.     if (mal = (long long *)memalign(alignment, 3)) {
  920.         fprintf(stderr, "    succeeded, block address ");
  921.         MPRINT(mal);
  922.         fprintf(stderr, "\n");
  923.  
  924.         fprintf(stderr, "    put zero in [pointer + 3]...\n");
  925.         clear = (char *) mal + 3;
  926.         *clear = '\0';
  927.  
  928.         fprintf(stderr, "    free it...\n");
  929.         free(mal);
  930.     } else {
  931.         fprintf(stderr, "    failed\n");
  932.     }
  933.  
  934.     /* a memalign to 16 bytes, check overrun */
  935.     fprintf(stderr, "  Another memalign() at 16-byte boundary, 3 bytes\n");
  936.     alignment = 16;
  937.     if (mal = (long long *)memalign(alignment, 3)) {
  938.         fprintf(stderr, "    succeeded, block address ");
  939.         MPRINT(mal);
  940.         fprintf(stderr, "\n");
  941.  
  942.         fprintf(stderr, "    put zero in [pointer + 3]...\n");
  943.         clear = (char *) mal + 3;
  944.         *clear = '\0';
  945.  
  946.         fprintf(stderr, "    then realloc() it to 11 bytes...\n");
  947.         if (simple = realloc(mal, 11)) {
  948.             fprintf(stderr, "      succeeded, block address ");
  949.             MPRINT(simple);
  950.             fprintf(stderr, "\n");
  951.  
  952.             fprintf(stderr, "      finally free it...\n");
  953.             free(simple);
  954.         } else {
  955.             fprintf(stderr, "      failed\n");
  956.             fprintf(stderr, "    Maybe free the old pointer?\n");
  957.             free(mal);
  958.         }
  959.     } else {
  960.         fprintf(stderr, "    failed\n");
  961.     }
  962.  
  963.     /* a memalign to 64 bytes */
  964.     fprintf(stderr, "  A memalign() at 64-byte boundary...\n");
  965.     alignment = 64;
  966.     if (mal = (long long *)memalign(alignment, 40*sizeof(long long))) {
  967.         fprintf(stderr, "    succeeded, block address ");
  968.         MPRINT(mal);
  969.         fprintf(stderr, "\n");
  970.  
  971.         fprintf(stderr, "    free it...\n");
  972.         free(mal);
  973.  
  974.         fprintf(stderr, "    How about free it twice?\n");
  975.         free(mal);
  976.     } else {
  977.         fprintf(stderr, "    failed\n");
  978.     }
  979.  
  980.     /* Bad alignment */
  981.     fprintf(stderr, "  Trying to get aligned at 48-byte boundary...\n");
  982.     if (simple = (char*)memalign(48, 1024)) {
  983.         fprintf(stderr, "    succeeded, block address ");
  984.         MPRINT(simple);
  985.         fprintf(stderr, "\n");
  986.     } else {
  987.         /* should be here */
  988.         fprintf(stderr, "    failed\n");
  989.     }
  990.     fprintf(stderr, "    But free it anyways...\n");
  991.     free(simple);
  992.  
  993.     /* a memalign to 16 bytes */
  994.     fprintf(stderr, "  A memalign(16, ~8K)...\n");
  995.     alignment = 16;
  996.     if (mal = (long long *)memalign(alignment, 4 * SIMPLE_SIZE)) {
  997.         fprintf(stderr, "    succeeded, block address ");
  998.         MPRINT(mal);
  999.         fprintf(stderr, "\n");
  1000.  
  1001.         fprintf(stderr, "    free it...\n");
  1002.         free(mal);
  1003.     } else {
  1004.         fprintf(stderr, "    failed\n");
  1005.     }
  1006.  
  1007.     /* bad size */
  1008.     fprintf(stderr, "  Trying to allocate 0 byte...\n");
  1009.     if (simple = (char*)malloc(0)) {
  1010.         fprintf(stderr, "    succeeded, block address ");
  1011.         MPRINT(simple);
  1012.         fprintf(stderr, "\n");
  1013.  
  1014.         fprintf(stderr, "    free it...\n");
  1015.         free(simple);
  1016.     } else {
  1017.         fprintf(stderr, "    failed\n");
  1018.     }
  1019.  
  1020.     /* size too big */
  1021.     fprintf(stderr, "  Trying to allocate a big chunk (~8K)...\n");
  1022.     if (simple = (char*)malloc(4 * SIMPLE_SIZE)) {
  1023.         fprintf(stderr, "    succeeded, block address ");
  1024.         MPRINT(simple);
  1025.         fprintf(stderr, "\n");
  1026.  
  1027.         fprintf(stderr, "    do not free it...\n");
  1028.     } else {
  1029.         fprintf(stderr, "    failed\n");
  1030.     }
  1031.  
  1032.     /* misaligned realloc address */
  1033.     fprintf(stderr, "  Trying to realloc() an odd address pointer...\n");
  1034.     if (simple = (char*)realloc((void*) ((char *)&ralph + 1), 64)) {
  1035.         fprintf(stderr, "    succeeded, block address ");
  1036.         MPRINT(simple);
  1037.         fprintf(stderr, "\n");
  1038.  
  1039.         fprintf(stderr, "    free it...\n");
  1040.         free(simple);
  1041.     } else {
  1042.         fprintf(stderr, "    failed\n");
  1043.     }
  1044.  
  1045.     /* realloc size too big */
  1046.     fprintf(stderr, "  Trying to realloc() a big chunk (~8K)...\n");
  1047.     if (simple = (char*)realloc(malloc(1), 4 * SIMPLE_SIZE)) {
  1048.         fprintf(stderr, "    succeeded, block address ");
  1049.         MPRINT(simple);
  1050.         fprintf(stderr, "\n");
  1051.  
  1052.         fprintf(stderr, "    free it...\n");
  1053.         free(simple);
  1054.     } else {
  1055.         fprintf(stderr, "    failed\n");
  1056.     }
  1057.  
  1058.     /* a simple malloc, followed by overrun */
  1059.     fprintf(stderr, "  Trying malloc(%d)...\n", 11);
  1060.     if (simple = (char *)malloc(11)) {
  1061.         fprintf(stderr, "    succeeded, block address ");
  1062.         MPRINT(simple);
  1063.         fprintf(stderr, "\n");
  1064.  
  1065.         fprintf(stderr, "    then write to array[size + 1]...\n");
  1066.         simple[11 + 1] = 0;
  1067.         fprintf(stderr, "    and realloc() to 1...\n");
  1068.         if (realloc(simple, 1)) {
  1069.             fprintf(stderr, "      succeeded!\n");
  1070.         } else {
  1071.             fprintf(stderr, "      failed!\n");
  1072.         }
  1073.         /* leaking */
  1074.     } else {
  1075.         fprintf(stderr, "    failed\n");
  1076.     }
  1077.  
  1078.     /* bad realloc address */
  1079.     fprintf(stderr, "  Trying to realloc(&an_auto_variable, 64)...\n");
  1080.     if (simple = (char*)realloc((void*) &ralph, 64)) {
  1081.         fprintf(stderr, "    succeeded, block address ");
  1082.         MPRINT(simple);
  1083.         fprintf(stderr, "\n");
  1084.  
  1085.         fprintf(stderr, "    free it...\n");
  1086.         free(simple);
  1087.     } else {
  1088.         fprintf(stderr, "    failed\n");
  1089.     }
  1090.  
  1091.     /* free of a misaligned address */
  1092.     fprintf(stderr, "  Freeing an odd address pointer...\n");
  1093.     free( (char *)(&stackvar) + 1 );
  1094.  
  1095.     /* free of a stack address */
  1096.     fprintf(stderr, "  Trying free(&an_auto_variable)...\n");
  1097.     free(&stackvar);
  1098.  
  1099.     /* allocate something but don't free */
  1100.     fprintf(stderr, "  Get one byte...\n");
  1101.     if (simple = (char*)malloc(1)) {
  1102.         fprintf(stderr, "    succeeded, block address ");
  1103.         MPRINT(simple);
  1104.         fprintf(stderr, "\n");
  1105.  
  1106.         fprintf(stderr, "    But I'm not going to free it...\n");
  1107.     } else {
  1108.         fprintf(stderr, "    failed\n");
  1109.     }
  1110.  
  1111.     /* print out message saying we are back */
  1112.     fprintf(stderr, "...\tmallocerrors completed (pid = %d)\n", getpid());
  1113.     return 0;
  1114. }
  1115.  
  1116. int
  1117. mallocerrors_extra()
  1118. {
  1119.     int ralph;
  1120.     char *simple;
  1121.  
  1122.     /* Log the event */
  1123.     genLog("start of mallocerrors-extra");
  1124.  
  1125.     /* a simple malloc, followed by underrun */
  1126.     fprintf(stderr, "  Trying malloc(%d) again...\n", SIMPLE_SIZE);
  1127.     ralph = -4;
  1128.     if (simple = (char *)malloc(SIMPLE_SIZE)) {
  1129.         fprintf(stderr, "    succeeded, block address ");
  1130.         MPRINT(simple);
  1131.         fprintf(stderr, "\n");
  1132.  
  1133.         fprintf(stderr, "    then write to array[-4]...\n");
  1134.         simple[ralph] = 1;
  1135.         fprintf(stderr, "    and free it...\n");
  1136.         free(simple);
  1137.     } else {
  1138.         fprintf(stderr, "    failed\n");
  1139.     }
  1140.  
  1141.     /* corrupt data */
  1142.     fprintf(stderr, "  Get memalign(16, 1)...\n");
  1143.     if (simple = (char*)memalign(16, 1)) {
  1144.         fprintf(stderr, "    succeeded, block address ");
  1145.         MPRINT(simple);
  1146.         fprintf(stderr, "\n");
  1147.  
  1148.         fprintf(stderr,
  1149.             "    Put 0xff in a byte 3 words ahead of it...\n");
  1150.         *(simple - 3 * sizeof(CLEAR_WORD)) = 0xff;
  1151.  
  1152.         fprintf(stderr, "    then free it...\n");
  1153.         free(simple);
  1154.     } else {
  1155.         fprintf(stderr, "    failed\n");
  1156.     }
  1157.  
  1158.     /* corrupt data */
  1159.     fprintf(stderr, "  Get memalign(16, 1) again...\n");
  1160.     if (simple = (char*)memalign(16, 1)) {
  1161.         fprintf(stderr, "    succeeded, block address ");
  1162.         MPRINT(simple);
  1163.         fprintf(stderr, "\n");
  1164.  
  1165.         fprintf(stderr,
  1166.             "    Put 0xff in a byte 3 words ahead of it...\n");
  1167.         *(simple - 3 * sizeof(CLEAR_WORD)) = 0xff;
  1168.  
  1169.         fprintf(stderr, "    then realloc it...\n");
  1170.         simple = realloc(simple, 1);
  1171.     } else {
  1172.         fprintf(stderr, "    failed\n");
  1173.     }
  1174.  
  1175.     /* a simple malloc, followed by underrun */
  1176.     fprintf(stderr, "  Trying malloc(%d) again...\n", 11);
  1177.     ralph = -4;
  1178.     if (simple = (char *)malloc(11)) {
  1179.         fprintf(stderr, "    succeeded, block address ");
  1180.         MPRINT(simple);
  1181.         fprintf(stderr, "\n");
  1182.  
  1183.         fprintf(stderr, "    then write to array[-4]...\n");
  1184.         simple[ralph] = 1;
  1185.         fprintf(stderr, "    and free it...\n");
  1186.         if (realloc(simple, 1)) {
  1187.             fprintf(stderr, "      succeeded!\n");
  1188.         } else {
  1189.             fprintf(stderr, "      failed!\n");
  1190.         }
  1191.         /* leaking */
  1192.     } else {
  1193.         fprintf(stderr, "    failed\n");
  1194.     }
  1195.  
  1196.     /* mallocate something */
  1197.     fprintf(stderr, "  Malloc one byte...\n");
  1198.     if (simple = (char*)malloc(1)) {
  1199.         fprintf(stderr, "    succeeded, block address ");
  1200.         MPRINT(simple);
  1201.         fprintf(stderr, "\n");
  1202.  
  1203.         fprintf(stderr, "    freeing it the first time\n");
  1204.         free(simple);
  1205.         fprintf(stderr, "    freeing it the second time\n");
  1206.         free(simple);
  1207.     } else {
  1208.         fprintf(stderr, "    failed\n");
  1209.     }
  1210.  
  1211.     /* print out message saying we are back */
  1212.     fprintf(stderr, "...\tmallocerrors-extra completed (pid = %d)\n", getpid());
  1213.     return 0;
  1214. }
  1215.  
  1216. /*=======================================================*/
  1217. /*    mp_mallocs - multi-process calling "mallocerrors()" */
  1218.  
  1219. #define    MP_MALLOCS    5
  1220.  
  1221. static void
  1222. mp_wrapper(void *ptr)
  1223. {
  1224.     barrier((barrier_t *) ptr, MP_MALLOCS);
  1225.     mallocerrors();
  1226.     mallocerrors_extra();
  1227. }
  1228.  
  1229. int
  1230. mp_mallocs()
  1231. {
  1232.     char *name;
  1233.     usptr_t *arena;
  1234.     barrier_t *bar;
  1235.     int i;
  1236.  
  1237.     /* Log the event */
  1238.     genLog("multi-process malloc tests");
  1239.  
  1240.     /* initialize the barrier */
  1241.     usconfig(CONF_ARENATYPE, US_SHAREDONLY);
  1242.  
  1243.     if (!(name = tempnam("/usr/tmp/", "mpme"))) {
  1244.         perror("TEMPNAM");
  1245.         return 0;
  1246.     }
  1247.     if (!(arena = usinit(name))) {
  1248.         perror("USINIT");
  1249.         return 0;
  1250.     }
  1251.     if (!(bar = new_barrier(arena))) {
  1252.         perror("NEW_BARRIER");
  1253.         return 0;
  1254.     }
  1255.     init_barrier(bar);
  1256.  
  1257.     /* create the processes */
  1258.     for (i = 0; i < MP_MALLOCS; i ++) {
  1259.         if (sproc(mp_wrapper, PR_SALL, (void*) bar) == -1) {
  1260.             perror("SPROC");
  1261.         }
  1262.     }
  1263.  
  1264.     fprintf(stderr, "...\tMP-me returning (pid = %d)\n", getpid());
  1265.     return 0;
  1266. }
  1267.  
  1268. #endif    /* NONSHARED */
  1269.  
  1270. /*=======================================================*/
  1271. /*    memthrash - allocate some memory, and thrash around in it */
  1272. int
  1273. memthrash()
  1274. {
  1275.     unsigned long    size;
  1276.     unsigned long     addr;
  1277.     void    *region;
  1278.     long    npages;
  1279.     long    i;
  1280.  
  1281.     /* Log the event */
  1282.     genLog("start of memthrash");
  1283.  
  1284.     /* compute the size */
  1285.     size = THRASHMB*1024*1024;
  1286.  
  1287.     pagesize = getpagesize();
  1288.     region = malloc(size + pagesize);
  1289.  
  1290.     if(region == NULL) {
  1291.         fprintf(stderr,
  1292.             "\tmemthrash failed; can't get %ld bytes.\n",
  1293.              size);
  1294.         return 0;
  1295.     }
  1296.  
  1297.     /* round address to page boundary */
  1298.     addr =(((unsigned long)region + pagesize -1) & (~(pagesize-1)));
  1299.     npages = size /pagesize;
  1300.  
  1301.     /* touch all the pages to force them in */
  1302.     for (i = 0; i < npages; i ++) {
  1303.         *(int *)(addr + i*pagesize) = i;
  1304.     }
  1305.  
  1306.     /* now free up the region */
  1307.     free(region);
  1308.  
  1309.     fprintf(stderr, "\tmemthrash completed, %ld pages.\n", npages);
  1310.  
  1311.     return 0;
  1312. }
  1313.  
  1314. /*=======================================================*/
  1315. /*    sproctest - sproc another thread, and do something in it */
  1316. int
  1317. sproctest()
  1318. {
  1319.     int index;
  1320.     int n = NSPROCS;
  1321.  
  1322.     /* Log the event */
  1323.     genLog("start of sproctest");
  1324.     fprintf(stderr, "sproc -- number of children %d\n", n);
  1325.  
  1326.     /* make sure the arena is big enough */
  1327.     usconfig(CONF_INITUSERS, (2*NSPROCS + 5) );
  1328.  
  1329.     for (index = 0; index < n; index++) {
  1330.         int child = sproc (sproctestchild, PR_SADDR);
  1331.         if (child == -1) {
  1332.             perror("SPROC CHILD");
  1333.         }
  1334.     }
  1335.  
  1336.     fprintf(stderr, "\tsproctest completed.\n");
  1337.  
  1338.     return 0;
  1339. }
  1340.  
  1341. void
  1342. sproctestchild(void *arg)
  1343. {
  1344.     int grand_child = sproc (sproctestgrandchild, PR_SADDR);
  1345.     if (grand_child == -1) {
  1346.         perror("SPROC GRANDCHILD");
  1347.     }
  1348.     sproctestgrandchild(arg);
  1349. }
  1350.  
  1351. void
  1352. sproctestgrandchild(void *arg)
  1353. {
  1354.     int index;
  1355.     long *sequence;
  1356.     long long argx;
  1357.  
  1358.     argx = (long long) arg;
  1359.  
  1360.     sequence = (long *) malloc(
  1361.         NSPROCMALLOCS * sizeof (long) );
  1362.  
  1363.     for (index = 0; index < NSPROCMALLOCS; index++) {
  1364.         sequence[index] = index;
  1365.     }
  1366.  
  1367.     free (sequence);
  1368.     fprintf(stderr,
  1369.         "sproc descendant, pid: %d, arg =0x%08llx completed.\n",
  1370.         getpid(), argx);
  1371. }
  1372.  
  1373. /*=======================================================*/
  1374. /*    usrtime - loop to use a bunch of user time */
  1375. int
  1376. usrtime()
  1377. {
  1378.     int    j;    /* temp value for loop */
  1379.     int    k;    /* temp value for loop */
  1380.     float    x;    /* temp variable for f.p. calculation */
  1381.  
  1382.     /* Log the event */
  1383.     genLog("start of usrtime");
  1384.  
  1385. #if 0
  1386.     for (k = 0; k < 100; k ++) {
  1387.         x = 0.0;
  1388.         for(j=0; j<100000; j++) {
  1389.             x = x + 1.0;
  1390.         }
  1391.     }
  1392. #endif
  1393.     anneal();
  1394.  
  1395.     fprintf(stderr, "\tusertime completed.\n");
  1396.  
  1397.     return 0;
  1398. }
  1399.  
  1400. /*
  1401.  *    Here's the array annealing routine, snipped out.  I've provided
  1402.  *    a local variable, "delay," that makes the annealing take longer;
  1403.  *    (very) roughly speaking, it takes about 10*delay iterations to
  1404.  *    converge.  The present default of 100 seems to give
  1405.  *    just-noticable change from step to step.
  1406.  */
  1407.  
  1408. #include <limits.h>
  1409. #include <stdlib.h>
  1410. #include <math.h>
  1411.  
  1412.  
  1413. typedef double  tArrayElem;    /* "long long" and "double" are fun, too */
  1414.  
  1415. #define TWODARRAYSIZE 40
  1416. #define MAX_ANNEAL 10000
  1417. const int twoDarraySize = TWODARRAYSIZE;    /* bigger is better */
  1418.  
  1419. typedef enum {randomly, sinusoidal, zero} tclampStyle;
  1420.  
  1421. tclampStyle clampStyle = zero;    /* sinusoidal is the coolest, but zero */
  1422.                 /* is the easiest to understand */
  1423.  
  1424. tArrayElem    twoDarray[TWODARRAYSIZE][TWODARRAYSIZE];
  1425.  
  1426. void    init2da();
  1427.  
  1428. void
  1429. init2da()
  1430. {
  1431.     /* Randomize interior, clamp edges to an interesting pattern */
  1432.  
  1433.     const double    circ    = 4*twoDarraySize - 4;
  1434.     const double pi        = 3.1415926535;
  1435.     const double incr    = 2*pi/circ;
  1436.     double phase        = 0.0;
  1437.     int i, j;
  1438.  
  1439.  
  1440.     /* Randomize the whole array, then clamp as specified in command */
  1441.     for (i = 0; i < (twoDarraySize); i++) {
  1442.         for (j = 0; j < (twoDarraySize); j++) {
  1443.             twoDarray[i][j] = 5. * drand48();
  1444.         }
  1445.     }
  1446.  
  1447.     switch (clampStyle) {
  1448.     case sinusoidal:
  1449.         for (i = 0, j = 0; i < twoDarraySize; i++) {
  1450.             twoDarray[i][j] = sinf(phase);
  1451.             phase += incr;
  1452.         }
  1453.         i--;    /* Undo loop-end incr */
  1454.  
  1455.  
  1456.         for (j = 1; j < twoDarraySize; j++) {
  1457.             twoDarray[i][j] = sinf(phase);
  1458.             phase += incr;
  1459.         }
  1460.         j--;
  1461.  
  1462.         for (i = i-1; i >= 0; i--) {
  1463.             twoDarray[i][j] = sinf(phase);
  1464.             phase += incr;
  1465.         }
  1466.         i++;
  1467.  
  1468.         for (j = j-1; j >= 0; j--) {
  1469.             twoDarray[i][j] = sinf(phase);
  1470.             phase += incr;
  1471.         }
  1472.         j++;
  1473.  
  1474.     
  1475.         for (i = 0, j = 0; i < twoDarraySize; i++) {
  1476.             twoDarray[i][j] = sinf(phase);
  1477.             phase += incr;
  1478.         }
  1479.         i--;    /* Undo loop-end incr */
  1480.  
  1481.  
  1482.         for (j = 1; j < twoDarraySize; j++) {
  1483.             twoDarray[i][j] = sinf(phase);
  1484.             phase += incr;
  1485.         }
  1486.         j--;
  1487.  
  1488.         for (i = i-1; i >= 0; i--) {
  1489.             twoDarray[i][j] = sinf(phase);
  1490.             phase += incr;
  1491.         }
  1492.         i++;
  1493.  
  1494.         for (j = j-1; j >= 0; j--) {
  1495.             twoDarray[i][j] = sinf(phase);
  1496.             phase += incr;
  1497.         }
  1498.         j++;
  1499.  
  1500.         for (i = 0, j = 0; i < twoDarraySize; i++) {
  1501.             twoDarray[i][j] = sinf(phase);
  1502.             phase += incr;
  1503.         }
  1504.         i--;    /* Undo loop-end incr */
  1505.  
  1506.  
  1507.         for (j = 1; j < twoDarraySize; j++) {
  1508.             twoDarray[i][j] = sinf(phase);
  1509.             phase += incr;
  1510.         }
  1511.         j--;
  1512.  
  1513.         for (i = i-1; i >= 0; i--) {
  1514.             twoDarray[i][j] = sinf(phase);
  1515.             phase += incr;
  1516.         }
  1517.         i++;
  1518.  
  1519.         for (j = j-1; j >= 0; j--) {
  1520.             twoDarray[i][j] = sinf(phase);
  1521.             phase += incr;
  1522.         }
  1523.         j++;
  1524.  
  1525.     
  1526.         for (i = 0, j = 0; i < twoDarraySize; i++) {
  1527.             twoDarray[i][j] = sinf(phase);
  1528.             phase += incr;
  1529.         }
  1530.         i--;        /* Undo loop-end incr */
  1531.  
  1532.  
  1533.         for (j = 1; j < twoDarraySize; j++) {
  1534.             twoDarray[i][j] = sinf(phase);
  1535.             phase += incr;
  1536.         }
  1537.         j--;
  1538.  
  1539.         for (i = i-1; i >= 0; i--) {
  1540.             twoDarray[i][j] = sinf(phase);
  1541.             phase += incr;
  1542.         }
  1543.         i++;
  1544.  
  1545.         for (j = j-1; j >= 0; j--) {
  1546.             twoDarray[i][j] = sinf(phase);
  1547.             phase += incr;
  1548.         }
  1549.         j++;
  1550.  
  1551.         break;
  1552.  
  1553.     case zero:
  1554.         for (i = 0; i < twoDarraySize; i++) {
  1555.             twoDarray[0][i] =
  1556.                 twoDarray[i][0] =
  1557.                 twoDarray[twoDarraySize-1][i] =
  1558.                 twoDarray[i][twoDarraySize-1] =
  1559.                 0;
  1560.         }
  1561.         break;
  1562.  
  1563.     case randomly:
  1564.  
  1565.     default:
  1566.         break;
  1567.     }
  1568.  
  1569. }
  1570.  
  1571. void
  1572. anneal()
  1573. {
  1574.     int    i,j,k;
  1575.     double delay = 100.0; 
  1576.  
  1577.     clampStyle = sinusoidal;
  1578.     init2da();
  1579.  
  1580.     /* Anneal only the interior (edges are clamped by init2da()) */
  1581.  
  1582.     /* To fix the failure to anneal in -sine mode, uncomment the cast
  1583.      *    to float.
  1584.      */
  1585.  
  1586.     for (k = 0; k < MAX_ANNEAL; k ++) {
  1587.         /* breakpoint here to watch the array */
  1588.         for (i = 1; i < (twoDarraySize-1); i++) {
  1589.             for (j = 1; j < (twoDarraySize-1); j++) {
  1590.                 twoDarray[i][j] =
  1591.                         ( twoDarray[i-1][j-1]
  1592.                         + twoDarray[i-1][j]
  1593.                         + twoDarray[i-1][j+1]
  1594.                         + twoDarray[i][j-1]
  1595.                         + twoDarray[i][j] * delay
  1596.                         + twoDarray[i][j+1]
  1597.                         + twoDarray[i+1][j-1]
  1598.                         + twoDarray[i+1][j]
  1599.                         + twoDarray[i+1][j+1] )
  1600.                     / (delay+8);
  1601.             }
  1602.         }
  1603.     }
  1604. }
  1605.  
  1606. /*=======================================================*/
  1607.  
  1608.  
  1609.  
  1610. /*    genCvtime (ttime)
  1611.  *        returns a pointer to a static string in the form:
  1612.  *        Thu  01 Jan 1990  00:00:00\0
  1613.  *        01234567890122345678901234
  1614.  *
  1615.  *    ttime is a pointer to a UNIX time in seconds since epoch
  1616.  *    library routine localtime() is used
  1617.  *
  1618.  */
  1619.  
  1620. static    char    genccbuf[26];
  1621. static    char    *days[] = {
  1622.          "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  1623. static    char    *months[] = {
  1624.          "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1625.          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  1626.  
  1627. char    *
  1628. genCvtime (time_t *ttime)
  1629. {
  1630.     struct    tm    *tp;
  1631.  
  1632.     /* get the date and time */
  1633.  
  1634.     tp = localtime(ttime);
  1635.  
  1636.     /* convert to string */
  1637.  
  1638.     sprintf(genccbuf, "%s  %02d %s %04d  %02d:%02d:%02d",
  1639.         days[tp->tm_wday],
  1640.         tp->tm_mday,
  1641.         months[tp->tm_mon],
  1642.         1900 + tp->tm_year,
  1643.         tp->tm_hour,
  1644.         tp->tm_min,
  1645.         tp->tm_sec);
  1646.  
  1647.     return(genccbuf);
  1648. }
  1649.  
  1650. static    char    genccbuf2[26];
  1651.  
  1652. char    *
  1653. genCvDeltaTime(struct timeval tempus)
  1654. {
  1655.     long seconds;
  1656.     long minutes;
  1657.     long hours;
  1658.  
  1659.     while (tempus.tv_usec < 0 ) {
  1660.         tempus.tv_sec --;
  1661.         tempus.tv_usec += 1000000;
  1662.     }
  1663.     
  1664.     seconds = tempus.tv_sec % 60;
  1665.     minutes = tempus.tv_sec/60;
  1666.     hours = minutes/60;
  1667.     minutes = minutes % 60;
  1668.     sprintf(genccbuf2, "%01ld:%02ld:%02ld.%03ld ",
  1669.         hours, minutes, seconds, tempus.tv_usec/1000);
  1670.     return(genccbuf2);
  1671. }
  1672.  
  1673. void
  1674. genTraceSnapTime()
  1675. {
  1676.     /* struct    timezone    tz; */
  1677.  
  1678.     (void) gettimeofday(&ttime, NULL);
  1679.  
  1680.     deltatime.tv_sec = ttime.tv_sec - starttime.tv_sec;
  1681.     deltatime.tv_usec = ttime.tv_usec - starttime.tv_usec;
  1682. }
  1683.  
  1684. void
  1685. genLog(char *event)
  1686. {
  1687.     time_t secs;
  1688.     char    buf[1024];
  1689.  
  1690.     genTraceSnapTime();
  1691.     secs = (time_t)ttime.tv_sec;
  1692.  
  1693.     sprintf(buf,
  1694.  "%s======== (%d) %24s %s.\n",
  1695.         genCvDeltaTime(deltatime),
  1696.         getpid(),
  1697.         event,
  1698.         genCvtime(&secs));
  1699.     fprintf(stderr, buf);
  1700. }
  1701.